package com.agileai.portal.extend.mobile;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.agileai.domain.DataRow;
import com.agileai.hotweb.common.BeanFactory;
import com.agileai.hotweb.common.HttpClientHelper;
import com.agileai.hotweb.common.StringTemplateLoader;
import com.agileai.hotweb.controller.core.BaseHandler;
import com.agileai.hotweb.domain.core.Profile;
import com.agileai.hotweb.domain.core.Resource;
import com.agileai.hotweb.domain.core.User;
import com.agileai.portal.bizmoduler.MenuItemPersonalManage;
import com.agileai.portal.bizmoduler.mobile.AngularWidgetManage;
import com.agileai.portal.controller.mobile.MobileDataProviderHandler;
import com.agileai.portal.driver.AttributeKeys;
import com.agileai.portal.driver.mobile.AngularWidget;
import com.agileai.portal.driver.model.LayoutContainer;
import com.agileai.portal.driver.model.MenuBar;
import com.agileai.portal.driver.model.MenuItem;
import com.agileai.portal.driver.model.Page;
import com.agileai.portal.driver.model.PortletWindowConfig;
import com.agileai.portal.driver.service.PortalConfigService;
import com.agileai.util.ListUtil;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;

public class MobileHelper {
	public static final String MobilePersonalKey = "MobilePersonalMenu";
	public static final String WxFirstMenuCode = "WxFirstMenuCode";
	
	public static final String UtilService = "'util.service'";
	public static final String PageKeyName = "page";
	public static final String PageTmplFileKey = "pageTmplFile";
	public static final String PageCtrlFileKey = "pageCtrlFile";
	
	private PortalConfigService portalConfigService = null;
	private AngularWidgetManage angularWidgetManage = null;
	private MenuItemPersonalManage menuItemPersonalManage = null;
	
	private MenuBar menuBar = null;
	private HttpServletRequest request = null;
	private User user = null;
	
	public MobileHelper(HttpServletRequest request){
		this.request = request;
		this.menuBar = (MenuBar)request.getAttribute(AttributeKeys.MENU_BAR_KEY);
		HttpSession httpSession = request.getSession();
		Profile profile = (Profile)httpSession.getAttribute(Profile.PROFILE_KEY);
		this.user = (User)profile.getUser();
		BeanFactory beanFactory = BeanFactory.instance();
		portalConfigService = (PortalConfigService)beanFactory.getBean("PortalConfigService");
		angularWidgetManage = (AngularWidgetManage)beanFactory.getBean("angularWidgetManageService");
		menuItemPersonalManage = (MenuItemPersonalManage)beanFactory.getBean("menuItemPersonalManageService");
	}
	
	/*
	public MobileHelper(MenuBar menuBar,User user){
		this.menuBar = menuBar;
		this.user = user;
		BeanFactory beanFactory = BeanFactory.instance();
		portalConfigService = (PortalConfigService)beanFactory.getBean("PortalConfigService");
		angularWidgetManage = (AngularWidgetManage)beanFactory.getBean("angularWidgetManageService");
		menuItemPersonalManage = (MenuItemPersonalManage)beanFactory.getBean("menuItemPersonalManageService");
	}
	*/
	
	public String getModulesDefine(){
		StringBuffer result = new StringBuffer();
		MenuItem[] allMenuItemList = menuBar.getAllMenuItemMap().values().toArray(new MenuItem[0]);
		for (int i=0;i < allMenuItemList.length;i++){
			if (i == 0)continue;
			MenuItem tempMenuItem = allMenuItemList[i];
	    	if (!MenuItem.Type.LeafNode.equals(tempMenuItem.getType())){
	    		continue;
	    	}
			
			JSONObject properties = tempMenuItem.getProperties();
			if (properties != null && properties.has("isModal")){
				try {
					String isModal = String.valueOf(properties.get("isModal"));
					if (isModal.equalsIgnoreCase("yes") || isModal.equalsIgnoreCase("y")
							|| isModal.equalsIgnoreCase("true")){
						continue;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			
			if (properties != null && properties.has("isPopover")){
				try {
					String isPopover = String.valueOf(properties.get("isPopover"));
					if (isPopover.equalsIgnoreCase("yes") || isPopover.equalsIgnoreCase("y")
							|| isPopover.equalsIgnoreCase("true")){
						continue;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}	
			
			if (properties != null && properties.has("isPopup")){
				try {
					String isPopup = String.valueOf(properties.get("isPopup"));
					if (isPopup.equalsIgnoreCase("yes") || isPopup.equalsIgnoreCase("y")
							|| isPopup.equalsIgnoreCase("true")){
						continue;
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}			
			
			String menuCode = tempMenuItem.getCode();
			String dependsModules = "";
			if (properties != null && properties.has("dependsModules")){
				try {
					dependsModules = properties.getString("dependsModules");					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (StringUtil.isNullOrEmpty(dependsModules)){
				dependsModules = UtilService;
			}else{
				if (!dependsModules.contains(UtilService)){
					dependsModules = dependsModules + "," + UtilService;
				}
			}
			result.append("angular.module('").append(menuCode).append("',[").append(dependsModules).append("]);").append("\r\n");
		}	
		
		return result.toString();
	}
	
	public boolean isCustomHeader(MenuItem menuItem){
		boolean result = false;
		JSONObject properties = menuItem.getProperties();
		if (properties != null && properties.has("customeHeader")){
			try {
				String customeHeader = String.valueOf(properties.get("customeHeader"));
				if (customeHeader.equalsIgnoreCase("yes") || customeHeader.equalsIgnoreCase("y")
						|| customeHeader.equalsIgnoreCase("true")){
					result = true;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	public boolean hasFooter(MenuItem menuItem){
		boolean result = false;
		JSONObject properties = menuItem.getProperties();
		if (properties != null && properties.has("hasFooter")){
			try {
				String hasFooter = String.valueOf(properties.get("hasFooter"));
				if (hasFooter.equalsIgnoreCase("yes") || hasFooter.equalsIgnoreCase("y")
						|| hasFooter.equalsIgnoreCase("true")){
					result = true;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}	
	
	public String getHideTabs(MenuItem menuItem){
		String result = "true";
		if (menuItem.isVisiable() && menuItem.getParent() == null &&  MenuItem.Type.LeafNode.equals(menuItem.getType())){
			result = "false";
		}
		return result;
	}
	
	public String getStateConfigs() {
		StringBuffer result = new StringBuffer();
		String viewTemplatePrefix = getViewTemplatePrefix();
		try {
		    MenuItem[] allMenuItemList = menuBar.getAllMenuItemMap().values().toArray(new MenuItem[0]);
		    for (int i=0;i < allMenuItemList.length;i++){
		    	if (i == 0){
		    		continue;
		    	}
		    	MenuItem tempMenuItem = allMenuItemList[i];
		    	if (!MenuItem.Type.LeafNode.equals(tempMenuItem.getType())){
		    		continue;
		    	}
		    	JSONObject properties = tempMenuItem.getProperties();
				if (properties != null && properties.has("isModal")){
					try {
						String isModal = String.valueOf(properties.get("isModal"));
						if (isModal.equalsIgnoreCase("yes") || isModal.equalsIgnoreCase("y")
								|| isModal.equalsIgnoreCase("true")){
							continue;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}		    	
		    	
				if (properties != null && properties.has("isPopover")){
					try {
						String isPopover = String.valueOf(properties.get("isPopover"));
						if (isPopover.equalsIgnoreCase("yes") || isPopover.equalsIgnoreCase("y")
								|| isPopover.equalsIgnoreCase("true")){
							continue;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}	
				
				if (properties != null && properties.has("isPopup")){
					try {
						String isPopup = String.valueOf(properties.get("isPopup"));
						if (isPopup.equalsIgnoreCase("yes") || isPopup.equalsIgnoreCase("y")
								|| isPopup.equalsIgnoreCase("true")){
							continue;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}	
				
				String menuCode = tempMenuItem.getCode();
				String pageId = tempMenuItem.getPageId();
				
				String stateURL = null;
				if (properties != null && properties.has("stateURL")){
					stateURL = properties.getString("stateURL");		
				}else{
					stateURL = "/"+menuCode;
				}
				
				String stateView = "";
				if (properties != null && properties.has("stateView")){
					stateView = properties.getString("stateView");		
				}else{
					stateView = "tab-"+menuCode;
				}
				result.append("$stateProvider.state('tab.").append(menuCode).append("',{").append("\r\n");
				result.append("url:'").append(stateURL).append("',").append("\r\n");
				if (properties != null && properties.has("pageCtrlFile")){
					result.append("views:{'").append(stateView).append("':{templateUrl:'").append(viewTemplatePrefix).append("/").append(menuCode).append(".ptml',controller:'").append(menuCode).append("-").append(PageKeyName).append("Ctrl'}").append("\r\n");		
				}else{
					result.append("views:{'").append(stateView).append("':{templateUrl:'").append(viewTemplatePrefix).append("/").append(menuCode).append(".ptml'}").append("\r\n");
				}
				
				Page page = portalConfigService.getPage(pageId);
				List<AngularWidget> widgetList = this.getAngularWidgetList(page);
		      	
		      	String controllerFiles = "'/portal/index?MobileDataProvider&actionType=retreiveCtrlFile&menuBarCode="+menuBar.getId()+"&menuCode="+menuCode+".js'";
		      	for (int j=0; j < widgetList.size();j++){
		      		AngularWidget widget = widgetList.get(j);
		      		String widgetCode = widget.getCode();
		      		String dynamicTemplateURL = "/portal/index?MobileDataProvider&actionType=retreiveTmplFile&menuBarCode="+menuBar.getId()+"&menuCode="+menuCode+"&widgetCode="+widgetCode;
		      		
		      		result.append(",'").append(widgetCode).append("@tab.").append(menuCode).append("':{templateUrl:'").append(dynamicTemplateURL).append("',controller:'").append(widgetCode).append("Ctrl'");
		      		result.append("}");
		      	}
		      	result.append("}").append("\r\n");
	      		result.append(",resolve:{'").append(menuCode).append("':['$ocLazyLoad',function($ocLazyLoad){").append("\r\n");
	      		result.append("return $ocLazyLoad.load(").append(controllerFiles).append(");").append("\r\n");
	      		result.append("}").append("\r\n");
	      		result.append("]}").append("\r\n");
	      		result.append("});").append("\r\n").append("\r\n");
		    }
		} catch (Exception e) {
			e.printStackTrace();
		}
	    return result.toString();
	}
	
	
	public String getTabConfigs(){
		StringBuffer result = new StringBuffer();
		try {
			  List<MenuItem> menuItemList = this.getTopVisiableMenuItemList();
			  for (int i=0;i < menuItemList.size();i++){
				  MenuItem tempMenuItem = menuItemList.get(i);
				  String menuCode = tempMenuItem.getCode();
				  String menuName = tempMenuItem.getName();
				  String icon = "bar-home";
				  if (tempMenuItem.getProperties() != null && tempMenuItem.getProperties().has("icon")){
					  icon = tempMenuItem.getProperties().getString("icon");
				  }
				  String title = menuName;
				  if (tempMenuItem.getProperties() != null && tempMenuItem.getProperties().has("title")){
					  title = tempMenuItem.getProperties().getString("title");
				  }
				  
				  boolean enableIconOnOff = false;
				  if (tempMenuItem.getProperties() != null && tempMenuItem.getProperties().has("enableIconOnOff")){
						String iconOnOff = String.valueOf(tempMenuItem.getProperties().get("enableIconOnOff"));
						if (iconOnOff.equalsIgnoreCase("yes") || iconOnOff.equalsIgnoreCase("y")
								|| iconOnOff.equalsIgnoreCase("true")){
							enableIconOnOff = true;
						}
				  }	
				  result.append("<ion-tab class=\"home-font\" title=\"").append(title).append("\"");
				  if (enableIconOnOff){
					  result.append(" icon=\"").append(icon).append("-on\" icon-on=\"").append(icon).append("-on\" icon-off=\"").append(icon).append("-off\"");					  
				  }else{
					  result.append(" icon=\"").append(icon).append("-on\" icon-on=\"").append(icon).append("\" icon-off=\"").append(icon).append("-outline\"");					  
				  }
				  result.append(" href=\"#/tab/").append(menuCode).append("\">").append("\r\n");
				  result.append("  <ion-nav-view name=\"tab-").append(menuCode).append("\"></ion-nav-view>").append("\r\n");
				  result.append("</ion-tab>").append("\r\n"); 
			  }
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result.toString();
	}
	
	public MenuItem getFirstValidMenuItem(){
		MenuItem result = null;
		List<MenuItem> tempList = menuBar.getMenuItemList();
		for (int i=0;i < tempList.size();i++){
			MenuItem menuItem = tempList.get(i);
			if (menuItem.getParent() == null
					&& MenuItem.Type.LeafNode.equals(menuItem.getType()) && menuItem.isVisiable()){
				result = menuItem;
				break;
			}
		}
		return result;
	}
	
	public String getViewTemplatePrefix(){
		String result = "/portal/"+ menuBar.getURLPrefix() + "/" + menuBar.getId();
		return result;
	}	
	
	
	public String getPageTemplateContent(MenuItem menuItem){
		String result = "";
		JSONObject properties = menuItem.getProperties();
		if (properties != null && properties.has(PageTmplFileKey)){
			try {
				String menuCode = menuItem.getCode();
				String cacheKey = menuCode+"!"+ PageKeyName;
				if (!AngularWidgetManage.TemplateFileContents.containsKey(cacheKey)){
					HttpClientHelper httpClientHelper = new HttpClientHelper();
					String pageTmplFile = properties.getString(PageTmplFileKey);
					String serverName = this.request.getServletContext().getInitParameter("serverName");
					String templateFileURL = serverName + pageTmplFile;
					String templateFileContent = httpClientHelper.retrieveGetReponseText(templateFileURL);	
					AngularWidgetManage.TemplateFileContents.put(cacheKey, templateFileContent);
				}
				result = AngularWidgetManage.TemplateFileContents.get(cacheKey);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}		
		return result;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public String getWidgetTemplateContent(MenuItem menuItem,AngularWidget angularWidget){
		String result = null;
		String menuCode = menuItem.getCode();
		String widgetCode = angularWidget.getCode();
		String cacheKey = menuCode+"!"+ widgetCode;
		if (!AngularWidgetManage.TemplateFileContents.containsKey(cacheKey)){
			HttpClientHelper httpClientHelper = new HttpClientHelper();
			String serverName = this.request.getServletContext().getInitParameter("serverName");
			String templateFileURL = serverName + angularWidget.getTemplateFile();
			String templateFileContent = httpClientHelper.retrieveGetReponseText(templateFileURL);	
			
			if (templateFileContent != null){
				StringWriter writer = new StringWriter();
				HashMap varRoot = new HashMap();
				varRoot.put("menuCode",menuCode);
				varRoot.put("widgetCode",widgetCode);
				
				this.parseContent(varRoot, templateFileContent, writer);
				
				String replacedContent = writer.toString();
				
				AngularWidgetManage.TemplateFileContents.put(cacheKey, replacedContent);			
			}
		}
		result = AngularWidgetManage.TemplateFileContents.get(cacheKey);
		return result;
	}
	
	
	@SuppressWarnings("rawtypes")
	private void parseContent(Map root,String template,StringWriter writer) {
		String encoding = "utf-8";
		try {
        	Configuration cfg = new Configuration();
        	cfg.setTemplateLoader(new StringTemplateLoader(template));  
        	cfg.setEncoding(Locale.getDefault(), encoding);
            cfg.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);
        	Template temp = cfg.getTemplate("");
        	temp.setEncoding(encoding);
            temp.process(root, writer);
            writer.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public MenuItem getIndexMenuItem(){
		MenuItem result = null;
		List<MenuItem> allMenuItemList = menuBar.getMenuItemList();
		if (allMenuItemList != null && allMenuItemList.size() > 0){
			result = allMenuItemList.get(0);
		}
		return result;
	}
	
	public String getTabCodeJsArray(List<AngularWidget> angularWidgetList){
		StringBuffer result = new StringBuffer("[");
		for (int i=0;i < angularWidgetList.size();i++){
			AngularWidget angularWidget = (AngularWidget)angularWidgetList.get(i);
			result.append("'");
			result.append(angularWidget.getCode());
			result.append("'");
			if (i < angularWidgetList.size()-1){
				result.append(",");				
			}
		}
		result.append("]");
		return result.toString();
	}

	public JSONObject buildPersonalJsonObject(List<AngularWidget> personalWidgets){
		JSONObject result = new JSONObject();
		try {
			JSONArray jsonArray = new JSONArray();
			result.put("widgets", jsonArray);
			for (int i=0;i < personalWidgets.size();i++){
				AngularWidget angularWidget = personalWidgets.get(i);
				JSONObject widgetJson = new JSONObject();
				widgetJson.put("id", angularWidget.getId());
				jsonArray.put(widgetJson);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	private List<AngularWidget> buildPersonalWidgets(String userPersonalText) throws JSONException{
		List<AngularWidget> angularWidgets = new ArrayList<AngularWidget>();
		JSONObject jsonObject = new JSONObject(userPersonalText);
		JSONArray jsonArray = jsonObject.getJSONArray("widgets");
		for (int i=0;i < jsonArray.length();i++){
			JSONObject widgetJson = jsonArray.getJSONObject(i);
			String widgetId = widgetJson.getString("id");
			AngularWidget angularWidget = angularWidgetManage.retrieveAngularWidget(widgetId);
			if (angularWidget != null){
				angularWidgets.add(angularWidget);				
			}					
		}
		return angularWidgets;
	}
	
	@SuppressWarnings("unchecked")
	private List<AngularWidget> getPageAngularWidgetListCache(String cacheKey){
		if (!getSessionAttributes().containsKey(cacheKey)){
			List<AngularWidget> tempList = new ArrayList<AngularWidget>();
			getSessionAttributes().put(cacheKey, tempList);
		}
		return (List<AngularWidget>)getSessionAttribute(cacheKey);
	}
	
	private List<AngularWidget> getPageAngularWidgetList(Page page){
		String pageId = page.getPageId();
		String cacheKey = "PageAngularWidgetCache"+pageId;
		List<AngularWidget> angularWidgets = getPageAngularWidgetListCache(cacheKey);
		if (angularWidgets.isEmpty()){
			List<PortletWindowConfig> porltetList = new ArrayList<PortletWindowConfig>();
			if (page.getMainContainerType().equals(LayoutContainer.ContainerType.COLUMN)){
				List<LayoutContainer> layoutContainerList = page.getLayoutContainers();
				for (int i=0;i < layoutContainerList.size();i++){
					LayoutContainer layoutContainer = layoutContainerList.get(i);
					List<PortletWindowConfig> pagePortletList = layoutContainer.getPortlets();
					porltetList.addAll(pagePortletList);
				}
			}else{
				List<LayoutContainer> layoutContainerList = page.getLayoutContainers();
				for (int i=0;i < layoutContainerList.size();i++){
					LayoutContainer layoutContainer = layoutContainerList.get(i);
					List<PortletWindowConfig> pagePortletList = layoutContainer.getPortlets();
					porltetList.addAll(pagePortletList);
				}
			}
			
			for (int i=0;i < porltetList.size();i++){
				PortletWindowConfig portletWindowConfig = porltetList.get(i);
				String portletId = portletWindowConfig.getId();
				if (user.containResouce(Resource.Type.Portlet, portletId)){
					String paramsXML = portletWindowConfig.getParams();
					if (StringUtil.isNotNullNotEmpty(paramsXML)){
						List<DataRow> portletProferences = ListUtil.toDataSet(paramsXML);
						HashMap<String,String> preferences = parsePreferences(portletProferences);
						String portletVisiable = preferences.get("portletVisiable");
						if (portletVisiable == null ||  "Y".equals(portletVisiable)){
							String widgetId = preferences.get("widgetId");
							AngularWidget angularWidget = angularWidgetManage.retrieveAngularWidget(widgetId);
							if (angularWidget != null){
								angularWidgets.add(angularWidget);				
							}
						}
					}						
				}
			}
		}
		return angularWidgets;
	}
	
	public AngularWidget getPageAngularWidget(Page page,String widgetCode){
		AngularWidget result = null;
		String pageId = page.getPageId();
		String widgetCacheKey = "PageAngularWidgetCache"+pageId+"."+widgetCode;
		
		if (this.getSessionAttributes().containsKey(widgetCacheKey)){
			result = (AngularWidget)this.getSessionAttribute(widgetCacheKey);
		}else{
			List<AngularWidget> angularWidgets = getPageAngularWidgetList(page);
			for (int i=0;i < angularWidgets.size();i++){
				AngularWidget angularWidget = angularWidgets.get(i);
				if (widgetCode.equals(angularWidget.getCode())){
					this.getSessionAttributes().put(widgetCacheKey, angularWidget);
					result = angularWidget;
					break;
				}
			}
		}
		return result;
	}
	
	private DataRow getUserPersonalRecord(String userCode, String menuItemId){
		DataRow dataRow = null;
		String userPersonDataRowKey = "UserPersonDataRowKey."+menuItemId;
		if (this.getSessionAttributes().containsKey(userPersonDataRowKey)){
			dataRow = (DataRow)this.getSessionAttribute(userPersonDataRowKey);
		}else{
			dataRow = menuItemPersonalManage.getRecord(userCode, menuItemId);
			this.getSessionAttributes().put(userPersonDataRowKey,dataRow);
		}
		return dataRow;
	}
	
	@SuppressWarnings("unchecked")
	public List<AngularWidget> getRestAngularWidgetList(Page page){
		List<AngularWidget> result = new ArrayList<AngularWidget>();
		String menuItemId = page.getMenuId();
		String userCode = user.getUserCode();
		
		DataRow dataRow = getUserPersonalRecord(userCode, menuItemId);
		if (dataRow != null && !StringUtil.isNullOrEmpty(dataRow.getString("USER_PERSONAL"))){
			List<AngularWidget> personalAngularWidgets = new ArrayList<AngularWidget>();
			HashMap<String,List<AngularWidget>> personalWidgets = (HashMap<String,List<AngularWidget>>)getSessionAttribute(MobilePersonalKey);
			if (personalWidgets != null && personalWidgets.get(menuItemId) != null){
				personalAngularWidgets = personalWidgets.get(menuItemId);
			}else{
				try {
					String userPersonalText = dataRow.getString("USER_PERSONAL");
					personalAngularWidgets = buildPersonalWidgets(userPersonalText);
				} catch (Exception e) {
					e.printStackTrace();
				}				
			}
			
			List<String> personalWidgetIds = new ArrayList<String>();
			for (int i=0;i < personalAngularWidgets.size();i++){
				AngularWidget angularWidget = personalAngularWidgets.get(i);
				String widgetId = angularWidget.getId();
				personalWidgetIds.add(widgetId);
			}
			
			List<String> addedIds = new ArrayList<String>();
			
			List<AngularWidget> angularWidgets = getPageAngularWidgetList(page);
			for (int i=0;i < angularWidgets.size();i++){
				AngularWidget angularWidget = angularWidgets.get(i);
				String widgetId = angularWidget.getId();
				if (!addedIds.contains(widgetId)){
					addedIds.add(widgetId);
					if (personalWidgetIds.contains(widgetId)){
						continue;
					}
					result.add(angularWidget);
				}
			}
		}
		return result;		
	}
	
	@SuppressWarnings("unchecked")
	public List<AngularWidget> getAngularWidgetList(Page page){
		List<AngularWidget> angularWidgets = null;
		String menuItemId = page.getMenuId();
		String userCode = user.getUserCode();
		MenuItem menuItem = portalConfigService.getMenuItem(menuItemId);
		
		if (menuItem.getProperties() != null && isPersonal(menuItem.getProperties())){
			DataRow dataRow = getUserPersonalRecord(userCode, menuItemId);
			
			if (dataRow != null && !StringUtil.isNullOrEmpty(dataRow.getString("USER_PERSONAL"))){
				HashMap<String,List<AngularWidget>> personalWidgets = (HashMap<String,List<AngularWidget>>)getSessionAttribute(MobilePersonalKey);
				if (personalWidgets != null && personalWidgets.get(menuItemId) != null){
					angularWidgets = personalWidgets.get(menuItemId);
				}else{
					try {
						String userPersonalText = dataRow.getString("USER_PERSONAL");
						angularWidgets = buildPersonalWidgets(userPersonalText);
						if (personalWidgets == null){
							personalWidgets = new HashMap<String,List<AngularWidget>>();
						}
						personalWidgets.put(menuItemId, angularWidgets);
						getSessionAttributes().put(MobilePersonalKey, personalWidgets);
					} catch (Exception e) {
						e.printStackTrace();
					}				
				}
			}else{
				angularWidgets = getPageAngularWidgetList(page);
			}			
		}else{
			angularWidgets = getPageAngularWidgetList(page);
		}
		return angularWidgets;
	}	
	
	private boolean isPersonal(JSONObject jsonObject){
		boolean result = false;
		try {
			if (jsonObject.has("personal") && (
					"y".equals(jsonObject.getString("personal"))
					|| "yes".equals(jsonObject.getString("personal"))
					|| "true".equals(jsonObject.getString("personal")))){
				result = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	private List<MenuItem> getTopVisiableMenuItemList(){
		List<MenuItem> result = new ArrayList<MenuItem>();
		List<MenuItem> tempList = menuBar.getMenuItemList();
		for (int i=0;i < tempList.size();i++){
			MenuItem menuItem = tempList.get(i);
			if (menuItem.getParent() == null
					&& MenuItem.Type.LeafNode.equals(menuItem.getType()) && menuItem.isVisiable()){
				result.add(menuItem);
			}
		}
		return result;
	}
	
	private HashMap<String,String> parsePreferences(List<DataRow> datasets){
		HashMap<String,String> result =  new HashMap<String,String>();
		if (datasets != null){
			for (int i=0;i < datasets.size();i++){
				DataRow row = datasets.get(i);
				String name = row.getString("name");
				String value = row.getString("value");
				result.put(name, value);
			}
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	private HashMap<String,Object> getSessionAttributes(){
		HttpSession session = request.getSession();
		Object temp = session.getAttribute(BaseHandler.HTTP_SESSION_MODEL_KEY);
		if (temp == null){
			HashMap<String,Object> sessionAttributes = new HashMap<String,Object>();
			session.setAttribute(BaseHandler.HTTP_SESSION_MODEL_KEY,sessionAttributes);
			temp = sessionAttributes;
		}
		return (HashMap<String,Object>)temp;
	}
	private Object getSessionAttribute(String key){
		Object result = getSessionAttributes().get(key);
		return result;
	}
	private Object getAndRemoveSessionAttribute(String key){
		Object result = getSessionAttributes().get(key);
		if (getSessionAttributes().containsKey(key)){
			getSessionAttributes().remove(key);
		}
		return result;
	}	
	
	public String getWxFirstMenuCode(){
		return (String)getAndRemoveSessionAttribute(WxFirstMenuCode);
	}
	
	public String getHeaderColor() throws JSONException{
		String result = null;
		String themeColor = MobileDataProviderHandler.getThemeColor(user);
		JSONObject themeObject = new JSONObject(themeColor);
		result = themeObject.getString("header");
		return result;
	}
	
	public String getFooterColor() throws JSONException{
		String result = null;
		String themeColor = MobileDataProviderHandler.getThemeColor(user);
		JSONObject themeObject = new JSONObject(themeColor);
		result = themeObject.getString("footer");
		return result;
	}
}